#include "app_mqtt.h"

#define MQTT_SERVER_URL "tcp://192.168.56.228:1883"
#define MQTT_CLIENT_ID "gate_client"
#define MQTT_TOPIC_PULL "pull"
#define MQTT_TOPIC_PUSH "push"

typedef struct
{
    MQTTClient mqtt_clinet;
    void (*recv_cb)(char *data, int dataLen);
} app_mqtt_t;

app_mqtt_t my_mqtt;

void conn_lost_cb(void *context, char *cause);
int msg_arrive_cb(void *context, char *topicName, int topicLen, MQTTClient_message *message);
void delivery_complete_cb(void *context, MQTTClient_deliveryToken dt);
gate_status_t app_mqtt_init(void (*recv_cb)(char *data, int dataLen))
{
    my_mqtt.recv_cb = recv_cb; // 保持回调函数
    /* 1. 串讲mqtt客户端 */
    if (MQTTClient_create(&my_mqtt.mqtt_clinet,
                          MQTT_SERVER_URL, MQTT_CLIENT_ID,
                          MQTTCLIENT_PERSISTENCE_NONE,
                          NULL) != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTTClient_create error");
        return ERROR;
    }

    log_info("MQTTClient_create ok");

    /* 2. 设置回调函数 */
    if (MQTTClient_setCallbacks(my_mqtt.mqtt_clinet,
                                NULL,
                                conn_lost_cb,
                                msg_arrive_cb,
                                delivery_complete_cb) != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTTClient_setCallbacks error");
        return ERROR;
    }
    log_info("MQTTClient_setCallbacks ok");

    /* 3. 连接服务器 */
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    if (MQTTClient_connect(my_mqtt.mqtt_clinet, &conn_opts) != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTTClient_connect error");
        return ERROR;
    }
    log_info("MQTTClient_connect ok");

    /* 4. 订阅主题 */
    if (MQTTClient_subscribe(my_mqtt.mqtt_clinet, MQTT_TOPIC_PULL, 1) != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTTClient_subscribe 主题 %s error", MQTT_TOPIC_PULL);
        return ERROR;
    }

    log_info("MQTTClient_subscribe ok");

    return OK;
}

gate_status_t app_mqtt_deInit(void)
{
    // 取消主题订阅
    MQTTClient_unsubscribe(my_mqtt.mqtt_clinet, MQTT_TOPIC_PULL);

    // 断线连接
    MQTTClient_disconnect(my_mqtt.mqtt_clinet, 2000);

    // 销毁客户端
    MQTTClient_destroy(&my_mqtt.mqtt_clinet);
}

void conn_lost_cb(void *context, char *cause)
{
    while (1)
    {
        MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
        if (MQTTClient_connect(my_mqtt.mqtt_clinet, &conn_opts) != MQTTCLIENT_SUCCESS)
        {
            log_error("MQTTClient_connect error");
            sleep(2);
            continue;
        }
        log_info("MQTTClient_connect ok");

        /* 4. 订阅主题 */
        if (MQTTClient_subscribe(my_mqtt.mqtt_clinet, MQTT_TOPIC_PULL, 1) != MQTTCLIENT_SUCCESS)
        {
            log_error("MQTTClient_subscribe 主题 %s error", MQTT_TOPIC_PULL);
            sleep(2);
            continue;
        }

        log_info("MQTTClient_subscribe ok");
        break;
    }
}

int msg_arrive_cb(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    /*  log_info("msg_arrive_cb topicName: %s, topicLen: %d, message: %s",
              topicName,
              topicLen,
              message->payload); */
    if (my_mqtt.recv_cb)
    {
        my_mqtt.recv_cb((char *)message->payload, message->payloadlen);
    }

    // 释放message和topic
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);

    return 1; // 返回1表示消息被正确处理
}

void delivery_complete_cb(void *context, MQTTClient_deliveryToken dt)
{
    log_debug("delivery_complete_cb: %d", dt);
}

/**
 * @brief 发送消息
 *
 * @param str 要发送的消息
 */
gate_status_t app_mqtt_send(char *str)
{
    if (MQTTClient_publish(my_mqtt.mqtt_clinet,
                           MQTT_TOPIC_PUSH,
                           strlen(str),
                           (void *)str,
                           0,
                           0,
                           NULL) != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTTClient_publish error");
        return ERROR;
    }
    log_info("MQTTClient_publish success");
    return OK;
}
